//////////////////////////////////////////////////////////////////////////////
//       Copyright (c) 2003 - RealTime Gaming.  All rights reserved.        //
//////////////////////////////////////////////////////////////////////////////

#ifndef USTRING_H
#define USTRING_H

#include "lib.h"
#include <tchar.h> // CSN-12948 - Upgrade to VS2012


namespace Library
{

//////////////////////////////////////////////////////////////////////////////
/// UCS2 String Class. Used to support unicode strings for multilingual.
//////////////////////////////////////////////////////////////////////////////
class PLIBEXP String
{
// Defines
public:
	class Character;
    enum { NPOS = 0xffffffff };

// Public Interface
public:
	// Construction/Destruction
	String( );
	String( const char* szString );
	String( const uint16* szString );
	String( uint16* pRawData, uint32 nSizeInBytes );
	String( const String& str );
	String( const Character& ch );
	virtual ~String();

	// Operators
	operator const uint16*  () const;
	const String& operator= ( const String& sString );
	const String& operator+=( const String& sString );
	const String  operator+ ( const String& sString ) const;
	
	bool8		  operator==( const uint16* sString ) const;
	bool8         operator==( const String& sString ) const;
	bool8         operator!=( const String& sString ) const;
	
	// Methods
	uint32	getLength  () const;
	uint32	getSize    () const;
	bool8	isEmpty    () const;
	void	empty      ();
	uint32	find       ( const String& sString, const uint32 sIndex = 0 ) const;
	uint32	find       ( const Character& sCharacter, const uint32 sIndex = 0 ) const;
	uint32	reverseFind( const String& sString, const uint32 sIndex = 0 ) const;
	uint32	reverseFind( const Character& sString, const uint32 sIndex = 0 ) const;
	void	replace    ( const String& sSearch, const String& sReplace );
	String	substring  ( uint32 index, uint32 length = NPOS ) const;
	uint32	toUInt32   (int32 base = 10) const;
	int32	toInt32	   (int32 base = 10) const;
	uint16	toUInt16   (int32 base = 10) const;
	void   	toLower    ();
	void    toUpper    ();
	void	trimLeft   ();
	void	trimRight  ();
	void	trim	   ();
    void    setChar    ( uint32 index, Character ch );

	uint16* getBuffer(const uint32 len);
	void	releaseBuffer();

	int32	sprintf(const char* format, ...);
	int32	sprintf(const uint16* format, ...);

	int32	caseCompare(int32 start, int32 length, const uint16* aString) const;
	int32	caseCompare(int32 start, int32 length, const String& aString) const;
	int32	caseCompare(const uint16 * aString) const;
	int32	caseCompare(const String & aString) const;

	int32	compare(int32 start, int32 length, const uint16 * aString) const;
	int32	compare(int32 start, int32 length, const String & aString) const;
	int32	compare(const uint16 * aString) const;
	int32	compare(const String & aString) const;

	uint32	serialize(void* pRawTo) const;
	uint32	deserialize(void* pRawFrom);

	uint32	serializeAnsi(void* pRawTo) const;
	uint32	deserializeAnsi(void* pRawFrom);

	static const String emptyString;

// Internal Helpers
protected:
	void copyString( const String& szString );
	void copyString( const uint16* szString );
	void copyString( const char*   szString );
	
	void copyString( const String& szString, uint32 nCharacters );
	void copyString( const uint16* szString, uint32 nCharacters );
	void copyString( const char*   szString, uint32 nCharacters );

    void concatenateString( const String& sString );
	void concatenateString( const uint16* sString );
	void concatenateString( const char* sString );

    void concatenateString( const String& sString, uint32 nCharacters );
	void concatenateString( const uint16* sString, uint32 nCharacters );
	void concatenateString( const char* sString, uint32 nCharacters );

// Members
protected:
	TCHAR*  m_pChar;            /**< Char pointer to internal data        */
	uint16* m_pData;			/**< Internal data pointer                */
	uint32  m_nAllocated;		/**< Number of bytes allocated            */
    uint32  m_nLength;          /**< Length of the string in characters   */
    bool8   m_bLocked;          /**< Flag indicating direct buffer access */

/////////////////////////////////////////////////////////////////////////
/// Nested character class.  This class encapsulates a string character.
/////////////////////////////////////////////////////////////////////////
public:
	class PLIBEXP Character
	{
	public:
		enum { null = 0x0000 };

	public:
		Character();
		Character( const char c );
		Character( const uint8 c );
		Character( const uint16 c );
		Character( const Character& c );
		~Character();

		operator uint16() const;

	private:
		uint16 m_c;
	};
};


namespace StringConversions
{
	bool8 PLIBEXP convert(char*, const char*, int32 size);
	bool8 PLIBEXP convert(uint16*, const uint16*, int32 size);
	bool8 PLIBEXP convert(char*, const uint16*, int32 size);
	bool8 PLIBEXP convert(uint16*, const char*, int32 size);

	bool8 PLIBEXP encodeUTF8(char* to, const uint16* from, int32 size);
	bool8 PLIBEXP decodeUTF8(uint16* to, const char* from, int32 size);
};
} // namespace Library

#endif // #ifndef USTRING_H
